package edu.hz.service.impl;

import edu.hz.dao.*;
import edu.hz.enums.DonationType;
import edu.hz.model.dto.*;
import edu.hz.model.entity.DonationCommentEntity;
import edu.hz.model.entity.DonationEntity;
import edu.hz.model.entity.UserDonationEntity;
import edu.hz.model.entity.UserEntity;
import edu.hz.service.DonationService;
import edu.hz.util.web.ApiResponse;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DonationServiceImpl implements DonationService {

    @Resource
    private DonationMapper donationMapper;

    @Resource
    private DonationCommentMapper donationCommentMapper;

    @Resource
    private UserDonationMapper userDonationMapper;

    @Resource
    private UserMapper userMapper;

    @Override
    public ApiResponse<Void> createDation(CreateDonationDto createDonationDto) {
        DonationEntity donationEntity = new DonationEntity();
        donationEntity.setName(createDonationDto.getName());
        donationEntity.setStart(createDonationDto.getStart());
        donationEntity.setEnd(createDonationDto.getEnd());
        donationEntity.setNeedMoney(createDonationDto.getNeedMoney());
        donationEntity.setCurrentMoney(0);
        donationEntity.setAuthor(createDonationDto.getAuthor());
        donationEntity.setProfile(createDonationDto.getProfile());
        donationEntity.setContent(createDonationDto.getContent());
        donationEntity.setIsTop(createDonationDto.getIsTop());
        
        int result = donationMapper.insertDonation(donationEntity);
        return result >0 ? ApiResponse.success(null) : ApiResponse.error("创建失败");
    }

    @Override
    public ApiResponse<List<HomeNewestDonationDto>> lastest10Donations() {
        List<DonationEntity> donationEntities = donationMapper.lastedDonations(10);
        List<HomeNewestDonationDto> retList = new ArrayList<>();
        donationEntities.forEach(e -> {
            HomeNewestDonationDto dto = new HomeNewestDonationDto();
            dto.setId(e.getId());
            dto.setName(e.getName());
            dto.setAuthor(e.getAuthor());
            dto.setCurrentMoney(e.getCurrentMoney());
            dto.setNeedMoney(e.getNeedMoney());

            BigDecimal progress = BigDecimal.ZERO;
            if (e.getNeedMoney() > 0) {
                progress = BigDecimal.valueOf(e.getCurrentMoney())
                        .divide(BigDecimal.valueOf(e.getNeedMoney()), 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
            }
            dto.setProgress(progress.setScale(2, RoundingMode.HALF_UP).doubleValue());

            dto.setSendTime(e.getSendTime());

            retList.add(dto);

        });

        return ApiResponse.success(retList);
    }

    @Override
    public ApiResponse<List<HomeTopContributingDonationDto>> top15ContributingProjects() {
        return ApiResponse.success(donationMapper.topContributingProjects(15));
    }

    @Override
    public ApiResponse<List<HomeMostMoneyDonationDto>> mostMoneyDonations() {

        List<DonationEntity> donations = donationMapper.mostMoney(15);
        List<HomeMostMoneyDonationDto> retList = new ArrayList<>();

        donations.forEach(d -> {
            HomeMostMoneyDonationDto dto = new HomeMostMoneyDonationDto();
            dto.setId(d.getId());
            dto.setName(d.getName());
            dto.setAuthor(d.getAuthor());
            dto.setCurrentMoney(d.getCurrentMoney());
            dto.setSendTime(d.getSendTime());

            BigDecimal progress = BigDecimal.ZERO;
            if (d.getNeedMoney() != 0) {
                progress = BigDecimal.valueOf(d.getCurrentMoney())
                        .divide(BigDecimal.valueOf(d.getNeedMoney()), 4, RoundingMode.HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
            }
            dto.setProgress(progress.setScale(2, RoundingMode.HALF_UP).doubleValue());
            retList.add(dto);

        });

        return ApiResponse.success(retList);
    }

    @Override
    public ApiResponse<List<HomeTopDonationDto>> top3Donations() {
        List<HomeTopDonationDto> donations = donationMapper.topDonations(3);
        return ApiResponse.success(donations);
    }

    @Override
    public ApiResponse<List<HomeNewestUserDonationDto>> last10UserDonations() {
        List<UserDonationEntity> userDonations = userDonationMapper.getLastUserDonations(10);
        List<HomeNewestUserDonationDto> retList = new ArrayList<>();

        userDonations.forEach(ud -> {
            HomeNewestUserDonationDto dto = new HomeNewestUserDonationDto();

            UserEntity user = userMapper.selectById(ud.getUserId());
            if (user != null) {
                // ApiResponse.error("用户不存在");
                dto.setUsername(user.getUsername());
            }

            DonationEntity donation = donationMapper.selectById(ud.getDonationId());
            if (donation != null) {
                dto.setDonationName(donation.getName());
            }

            DonationType donationType = DonationType.fromValue(ud.getDonationType());
            String donationTypeValue = donationType == DonationType.MONEY ? "捐款" : "捐物";
            dto.setDonationType(donationTypeValue);

            dto.setDonationAmount(ud.getMoney());
            dto.setDonationTime(ud.getDonationTime());

            retList.add(dto);

        });

        return ApiResponse.success(retList);
    }

    @Override
    public ApiResponse<List<DonationHoleListDto>> allDonations() {
        List<DonationEntity> donations = donationMapper.allDonations();
        List<DonationHoleListDto> retList = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();

        donations.forEach(d -> {
            DonationHoleListDto dto = new DonationHoleListDto();
            dto.setId(d.getId());
            dto.setName(d.getName());
            dto.setAuthor(d.getAuthor());
            dto.setNeedMoney(d.getNeedMoney());
            dto.setCurrentMoney(d.getCurrentMoney());

            BigDecimal progress = BigDecimal.ZERO;
            if (d.getNeedMoney() != 0) {
                progress = BigDecimal.valueOf(d.getCurrentMoney())
                        .divide(BigDecimal.valueOf(d.getNeedMoney()), 4, BigDecimal.ROUND_UP)
                        .multiply(BigDecimal.valueOf(100));
            }
            dto.setProgress(progress.setScale(2, RoundingMode.HALF_UP).doubleValue());
            dto.setSendTime(d.getSendTime());
            // 计算时间状态
            if (now.isBefore(d.getEnd()) && now.isAfter(d.getStart())) {
                dto.setTimeStatus("进行中");
            } else {
                dto.setTimeStatus("未开始或已结束");
            }

            // 筹措进度
            if (d.getCurrentMoney() >= d.getNeedMoney()) {
                dto.setDonationStatus("已经完成资金筹措");
            } else {
                dto.setDonationStatus("未完成资金筹措");
            }

            retList.add(dto);

        });


        return ApiResponse.success(retList);
    }

    @Override
    public DonationHoleListContentDto donationInfo(Integer id) {
        DonationHoleListContentDto dto = new DonationHoleListContentDto();
        DonationEntity donation = donationMapper.selectById(id);
        if (donation == null) {
            return null;
        }
        dto.setId(donation.getId());
        dto.setName(donation.getName());
        dto.setStart(donation.getStart());
        dto.setEnd(donation.getEnd());
        dto.setNeedMoney(donation.getNeedMoney());
        dto.setCurrentMoney(donation.getCurrentMoney());
        BigDecimal progress = BigDecimal.ZERO;
        if (donation.getNeedMoney() != 0) {
            progress = BigDecimal.valueOf(donation.getCurrentMoney())
                    .divide(BigDecimal.valueOf(donation.getNeedMoney()), 4, RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
        }
        dto.setProgress(progress.setScale(2, RoundingMode.HALF_UP).doubleValue());
        if (donation.getCurrentMoney() >= donation.getNeedMoney()) {
            dto.setDonationStatus("已完成资金筹措");
        } else {
            dto.setDonationStatus("未完成资金筹措");
        }
        dto.setAuthor(donation.getAuthor());
        dto.setProfile(donation.getProfile());
        dto.setContent(donation.getContent());
        dto.setSendTime(donation.getSendTime());

        // 用户评论
        List<DonationCommentEntity> commentEntities = donationCommentMapper.selectByDonationId(id);
        List<DonationContentCommentDto> commentRetList = new ArrayList<>();
        commentEntities.forEach(c -> {
            DonationContentCommentDto cDto = new DonationContentCommentDto();
            UserEntity user = userMapper.selectById(c.getUserId());
            if (user != null) {
                cDto.setUsername(user.getUsername());
                cDto.setContent(c.getComment());
                cDto.setCommentTime(c.getCommentTime());
            }
            commentRetList.add(cDto);
        });
        dto.setComments(commentRetList);

        // 项目捐赠人列表
        List<UserDonationEntity> userDonationEntities = userDonationMapper.selectByDonationId(id);
        Map<Integer, DonationContentUserDto> userMap = new HashMap<>();
        userDonationEntities.forEach(ud -> {
            UserEntity user = userMapper.selectById(ud.getUserId());
            if (user != null) {
                DonationContentUserDto userDto = userMap.getOrDefault(user.getId(), new DonationContentUserDto());
                userDto.setUsername(user.getUsername());
                userDto.setUserTitle(user.getTitle());
                if (userDto.getContributeCount() == null) {
                    userDto.setContributeCount(0);
                }
                userDto.setContributeCount(userDto.getContributeCount() + 1);
                if (userDto.getContributeMoney() == null) {
                    userDto.setContributeMoney(0);
                }
                userDto.setContributeMoney(userDto.getContributeMoney() + ud.getMoney());
                if (userDto.getLastContributeTime() == null || ud.getDonationTime().isAfter(userDto.getLastContributeTime())) {
                    userDto.setLastContributeTime(ud.getDonationTime());
                }
                userMap.put(user.getId(), userDto);
            }
        });
        dto.setUsers(new ArrayList<>(userMap.values()));

        // 项目的捐赠详情
        List<DonationContentItemDto> itemRetList = new ArrayList<>();
        userDonationEntities.forEach(ud -> {
            DonationContentItemDto itemDto = new DonationContentItemDto();
            DonationType donationType = DonationType.fromValue(ud.getDonationType());
            String donationTypeValue = donationType == DonationType.MONEY ? "捐款" : "捐物";
            itemDto.setDonationType(donationTypeValue);

            itemDto.setDonationDetail(ud.getDetail());
            itemDto.setMoney(ud.getMoney());

            UserEntity user = userMapper.selectById(ud.getUserId());
            if (user != null) {
                itemDto.setUsername(user.getUsername());
            } else {
                itemDto.setUsername("佚名");
            }
            itemDto.setContributeTime(ud.getDonationTime());
            itemRetList.add(itemDto);
        });
        dto.setItems(itemRetList);

        return dto;
    }

}
